﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace zaklad_rtv
{
    /// <summary>
    /// Interaction logic for ServiceList.xaml
    /// </summary>
    public partial class ServiceList
    {
        private bool _filterActive;

        public ServiceList()
        {
            InitializeComponent();
        }

        private void ConfirmDelete(object sender, RoutedEventArgs e)
        {
            var result = MessageBox.Show("Czy na pewno chcesz usunąć tę naprawę z bazy danych?", "Usuwanie naprawy", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result.Equals(MessageBoxResult.Yes))
            {
                var serviceToDelete = _listView.SelectedItem as Service;
                if (serviceToDelete != null)
                {
                    ObjectCollection.Remove(serviceToDelete);
                    MainWindow.DBHelper.Delete(serviceToDelete);
                    RefreshList();
                }
            }
        }

        public bool IsAnyFilterProvided()
        {
            var textboxes = LogicalTreeUtils.GetLogicalChildCollection<TextBox>(_filterExpander);
            return textboxes.Any(tb => !String.IsNullOrEmpty(tb.Text.Trim()));
        }

        protected override void RefreshList()
        {
            _listView.ItemsSource = null;
            _listView.ItemsSource =
                from s in ObjectCollection
                orderby s.Number descending
                select s;
            foreach (var column in ((GridView)_listView.View).Columns)
            {
                column.Width = column.ActualWidth;
                column.Width = double.NaN;
            }
        }

        protected override ICriteria<Service> ComposeCriteria()
        {
            var criteria = new MultipleCriteria<Service>();
            var clientFilter = _filterClient.Text.Trim();
            var costFromFilter = _filterCostFrom.Text.Trim();
            var costToFilter = _filterCostTo.Text.Trim();
            var dateFromFilter = _filterDateFrom.Text.Trim();
            var dateToFilter = _filterDateTo.Text.Trim();
            var descFilter = _filterDesc.Text.Trim();
            var typeFilter = _filterType.Text.Trim();
            if (!string.IsNullOrEmpty(clientFilter))
            {
                criteria.AddCriterion(new SingleCriterion<Service>(s => s.Client.FullString.ContainsIgnoreCase(clientFilter)));
            }
            if (!string.IsNullOrEmpty(costFromFilter))
            {
                var costFromValue = CostConverter.TextToNumber(costFromFilter);
                criteria.AddCriterion(new SingleCriterion<Service>(s => s.Cost >= costFromValue));
            }
            if (!string.IsNullOrEmpty(costToFilter))
            {
                var costToValue = CostConverter.TextToNumber(costToFilter);
                criteria.AddCriterion(new SingleCriterion<Service>(s => s.Cost <= costToValue));
            }
            if (!string.IsNullOrEmpty(dateFromFilter))
            {
                var dateFromValue = DateTime.Parse(dateFromFilter);
                criteria.AddCriterion(new SingleCriterion<Service>(s => s.BeginServiceDate >= dateFromValue));
            }
            if (!string.IsNullOrEmpty(dateToFilter))
            {
                var dateToValue = DateTime.Parse(dateToFilter);
                criteria.AddCriterion(new SingleCriterion<Service>(s => s.BeginServiceDate <= dateToValue));
            }
            if (!string.IsNullOrEmpty(descFilter))
            {
                criteria.AddCriterion(new SingleCriterion<Service>(s => s.DefectDescription.ContainsIgnoreCase(descFilter)));
            }
            if (!string.IsNullOrEmpty(typeFilter))
            {
                criteria.AddCriterion(new SingleCriterion<Service>(s => s.HardwareType.ContainsIgnoreCase(typeFilter)));
            }
            return criteria;
        }

        protected override void ViewFilteredList(ICriteria<Service> criteria)
        {
            var allServices = MainWindow.DBHelper.GetAllService();
            var filteredCollection = new Collection<Service>();
            foreach (var service in allServices.Where(criteria.IsMatched))
            {
                filteredCollection.Add(service);
            }
            ObjectCollection = filteredCollection;
            RefreshList();
        }

        private void GoToEdit(object sender, RoutedEventArgs e)
        {
            ((ServiceForm)MainWindow._serviceFormTab.Content).EditObject = _listView.SelectedItem as Service;
            MainWindow.ChangeActiveTab(MainWindow.Tabs.ServiceForm);
        }

        private void GoToNew(object sender, RoutedEventArgs e)
        {
            _listView.SelectedItem = null;
            ((ServiceForm)MainWindow._serviceFormTab.Content).EditObject = null;
            MainWindow.ChangeActiveTab(MainWindow.Tabs.ServiceForm);
        }

        public void ServiceAdded(Service service)
        {
            ObjectCollection.Add(service);
            if (_filterActive)
            {
                Filter();
            }
            else
            {
                RefreshList();
            }
        }

        public void ServiceEdited(Service service)
        {
            RefreshList();
        }

        private void SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_listView.SelectedItem != null)
            {
                ((ServiceForm)MainWindow._serviceFormTab.Content).EditObject = _listView.SelectedItem as Service;
            }
            else
            {
                ((ServiceForm)MainWindow._serviceFormTab.Content).EditObject = null;
            }
        }

        private void Print(object sender, RoutedEventArgs e)
        {
            var service = _listView.SelectedItem as Service;
            var data = new Dictionary<String, String>();
            if (service != null)
            {
                data.Add(StringConstants.AddressPlaceholder, service.Client.Address);
                data.Add(StringConstants.BeginServiceDatePlaceholder, service.BeginServiceDate.ToString(StringConstants.DateFormat));
                data.Add(StringConstants.CostPlaceholder, CostConverter.NumberToText(service.Cost));
                data.Add(StringConstants.DefectDescriptionPlaceholder, service.DefectDescription);
                data.Add(StringConstants.EndServiceDatePlaceholder, service.EndServiceDate.Equals(DateTime.MaxValue) ? "" : service.EndServiceDate.ToString(StringConstants.DateFormat));
                data.Add(StringConstants.FooterPlaceholder, MainWindow.DBHelper.GetConfig(StringConstants.ConfigFooterName).ConfigValue);
                data.Add(StringConstants.HardwareTypePlaceholder, service.HardwareType);
                data.Add(StringConstants.NamePlaceholder, service.Client.FirstName + " " + service.Client.LastName);
                data.Add(StringConstants.NumberPlaceholder, service.Number + "/" + service.BeginServiceDate.Year);
                data.Add(StringConstants.RemarksPlaceholder, service.Remarks);
                data.Add(StringConstants.ServiceDescriptionPlaceholder, service.ServiceDescription);
                data.Add(StringConstants.TelephonePlaceholder, service.Client.Telephone);
            }
            var type = PrintType.Ticket;
            if (sender == _btnPrintTicket)
            {
                type = PrintType.Ticket;
            }
            else if (sender == _btnPrintFinalSummary)
            {
                type = PrintType.FinalSummary;
            }
            var confirmation = new PrintableConfirmation(type, data);
            confirmation.PrintConfirmation();
        }

        private void CollapseExpander(object sender, MouseButtonEventArgs args)
        {
            _filterExpander.IsExpanded = false;
        }

        private void _filterExpander_OnMouseLeave(object sender, MouseEventArgs e)
        {
            MainWindow.MouseLeftButtonDown += CollapseExpander;
        }

        private void _filterExpander_OnMouseEnter(object sender, MouseEventArgs e)
        {
            MainWindow.MouseLeftButtonDown -= CollapseExpander;
        }

        public void DoFilter(object sender, RoutedEventArgs e)
        {
            if (IsAnyFilterProvided())
            {
                Filter();
                _filterActive = true;
                _filterExpanderHeader.FontWeight = FontWeights.Bold;
            }
            CollapseExpander(null, null);
        }

        private void ClearFilter(object sender, RoutedEventArgs e)
        {
            var textboxes = LogicalTreeUtils.GetLogicalChildCollection<TextBox>(_filterExpander);
            foreach (var textbox in textboxes)
            {
                textbox.Clear();
            }
            ObjectCollection = new Collection<Service>(MainWindow.DBHelper.GetAllService());
            RefreshList();
            _filterActive = false;
            _filterExpanderHeader.FontWeight = FontWeights.Normal;
            CollapseExpander(null, null);
        }
    }
}
